package com.bitoon.basketdudes.ws;

import java.io.File;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

import com.bitoon.basketdudes.jpa.AspectoEquipo;
import com.bitoon.basketdudes.jpa.CruceDivision;
import com.bitoon.basketdudes.jpa.Elo;
import com.bitoon.basketdudes.jpa.Equipo;
import com.bitoon.basketdudes.jpa.EstEquipo;
import com.bitoon.basketdudes.jpa.EstJugador;
import com.bitoon.basketdudes.jpa.HVisita;
import com.bitoon.basketdudes.jpa.HVisitaPK;
import com.bitoon.basketdudes.jpa.Juego;
import com.bitoon.basketdudes.jpa.Jugador;
import com.bitoon.basketdudes.jpa.MJugador;
import com.bitoon.basketdudes.jpa.MarcaUser;
import com.bitoon.basketdudes.jpa.Partida;
import com.bitoon.basketdudes.jpa.PersistenceManager;
import com.bitoon.basketdudes.jpa.Plantilla;
import com.bitoon.basketdudes.jpa.PlantillaPK;
import com.bitoon.basketdudes.jpa.Ranking;
import com.bitoon.basketdudes.jpa.Region;
import com.bitoon.basketdudes.jpa.Semanal;
import com.bitoon.basketdudes.jpa.Servicio;
import com.bitoon.basketdudes.jpa.Sesion;
import com.bitoon.basketdudes.jpa.Talento;
import com.bitoon.basketdudes.jpa.UltimosPartidos;
import com.bitoon.basketdudes.jpa.Usuario;
import com.bitoon.basketdudes.jpa.Visita;
import com.bitoon.basketdudes.jpa.VisitaPK;

public class LoginAction {

    protected EntityManagerFactory emfBasket = null;

    Usuario m_usuario = null;

    protected Logger log = Logger.getLogger(LoginAction.class);
    Configuracion conf = null;
    private static String privatePath = null;

    private static final short TITULAR = 1;
    private static final short SUPLENTE = 0;

    private static final int ROOKIE = 0;
    private static final int NOVICE = 1;
    private static final int EXPERTO = 2;
    private static final int PRO = 3;

    private static final int MAX_EQUIPOS_POR_USUARIO = 4;

    public LoginAction() {

        //String catalogos[] = {"jpa_catalogo", "jpa_basket"};
        try {
            // JPA Units
            emfBasket = PersistenceManager.getInstance().getEntityManagerFactory("jpa_basket");
            conf = Configuracion.getInstance();
        } catch (Exception e) {
            log.error("[ERROR][constructor]: No se pudo conectar a la base de datos: ", e);
        }

        privatePath = conf.BuscarValorConfiguracionString("path.avatar");
    }

    public EntityManagerFactory getEntityManager () {
        return emfBasket;
    }

    
    public String wsPartnerNick(HttpServletRequest request, HttpServletResponse response) {
        // Consulta el partner de un nick
        
        String          retorno = "";
        EntityManager em = null;
        try {
            em = emfBasket.createEntityManager();

            String    nick_buscar  = request.getParameter("nick");
            try {
                Query q = em.createNamedQuery("Usuario.findByNick");
                q.setParameter("nick", nick_buscar.toLowerCase().trim());
                Usuario u = (Usuario)q.getSingleResult();

                retorno="error=0;partner="+u.getRegion().getPartner().getId();
                
            } catch ( NoResultException nores) {
                retorno="error=-60;description=new";
            }
            
        } catch (Exception x) {
            log.error("[ERROR][wsPartnerNick]: ", x);
            retorno = "error=-100;description=unknow";
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return retorno;
    }    
    
    /*
    Web Service de login
    ====================

    se recibe un nick y una password (encriptada en SHA1)

    si la pareja nick/password no existe, se devuelve un error

    si existe, se crea una sesión en el servidor web. Ese id_session se
    graba en la base de datos de CATALOGO, para saber que el usuario ID_USUARIO
    se ha logado con ese ID_SESSION, y la fecha en la que se ha creado

    antes de este paso, se comprueba que no exista ninguna sesión anterior con
    el mismo ID_USUARIO, ya que un mismo ID_USUARIO no puede abrir más de una
    sesión al mismo tiempo en los servidores de catálogo/juego. En caso de que
    existan, se borran de la base de datos.

     *
     * @return
     *
     *      > 0 - el identificador del usuario
     *      -10 - cuenta sin activación de email
     *      -20 - cuenta baneada
     *      -30 - version incorrecta
     *      -40 - juego incorrecto
     *
     * Si el user/password existe:
     *
     * idsesion=<SESSION_ID>;equipos={<EQUIPOS>}
     */

    //public String wsLogin(String user, String pass, HttpSession miSesion) {

    public void wsLogin(HttpServletRequest request, HttpServletResponse response) {
        String output       = "";
        OutString aux_output= new OutString();
        int partner_id      = 1; // Por defecto Bitoon
        m_usuario = null;

        EntityManager em = null;
        try {
            em = emfBasket.createEntityManager(); // check 10.08.2012
            em.getTransaction().begin();
            log.debug("Antes Decoder " + request.getParameter("user")  );

            String user = URLDecoder.decode(request.getParameter("user"),"UTF-8");

            log.debug("Antes Decoder " + request.getParameter("user") + " despues decoder " + user );

            String pass = request.getParameter("pass");
            int juego_id = Integer.parseInt(request.getParameter("juego"));
            int version = Integer.parseInt(request.getParameter("version"));
            if (request.getParameter("partner")!= null ) {
                partner_id = Integer.parseInt(request.getParameter("partner"));
                log.debug(" partner " + partner_id  );                
            }
            
            HttpSession miSesion = request.getSession(true);
            String infoLogin = "";
            String idSesion = null;
            int exito = 0;
            int codError = 0;
            long ini = new GregorianCalendar().getTimeInMillis();

            if (user != null && pass != null) {

                // Comprobar el login contra la base de datos
                if (log.isDebugEnabled()) {
                    log.debug("Comprobando " + user + "/" + pass);
                    log.debug("Antes comprobarLogin"+ user + " password "+ pass);
                }

                int idUsuario = comprobarLogin(user, pass, juego_id, partner_id, aux_output, request);

                if (idUsuario > 0) { // Existe el par user/pass

                    // Comprobamos la versión del cliente
                    Query q = em.createNamedQuery("Juego.findById");
                    q.setParameter("id", juego_id);
                    List<Juego> l = (List<Juego>)q.getResultList();

                    if (l.isEmpty()) {
                        codError = -40; // Juego incorrecto
                    } else {
                        if ( l.get(0).getVersion()<= version  ) {
                            // Se graba en la base de datos el par id_usuario/id_sesion
                            idSesion = miSesion.getId();
                            miSesion.setAttribute("activo", true);
                            exito = grabaSesion(idUsuario, idSesion, em);

                            if (exito == 1) { // Se ha grabado bien la sesion en la bd
                                codError = 0;
                                // Obtener los equipos del usuario idUsuario
                                infoLogin = dameInfoLogin(idUsuario);
                            } else {
                                codError = -1;
                            }
                        } else {
                            codError = -30; // Versión Incorrecta
                        }
                    }
                    log.info("Sesion " + idSesion + " asignada a " + user + "(codError:" + codError + ")");
                } else {
                    codError = idUsuario;
                    if (log.isDebugEnabled()) {
                        log.debug("Error [2]" + codError);
                    }
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Error [3] Incorrect parameters dont exists existe user o pass");
                }
                codError = -3;
            }

            long fin = new GregorianCalendar().getTimeInMillis();

            if (exito==1) {
                output = "idsesion=" + idSesion + ";" + infoLogin + ";f=" + Util.FechaFormateada(new Date()) +";";
                if ( m_usuario != null ){
                    Calendar fecha = Calendar.getInstance();

                    if ( m_usuario.getfEula() != null) {
                        fecha.setTime(m_usuario.getfEula());
                        output+="eula="+  fecha.get(Calendar.YEAR);
                        if ( fecha.get(Calendar.MONTH) <10 ) {
                            output+="0";
                        }
                        output+=fecha.get(Calendar.MONTH)+1;
                        if ( fecha.get(Calendar.DATE) <10 ) {
                            output+="0";
                        }
                        output+=fecha.get(Calendar.DATE)  +";";
                    } else {
                        output+="eula=19700101;";
                    }
                }
                output+="region="+m_usuario.getRegion().getId()+";";
                output+="lobbys={" + listaServiciosRegion(em,"lobby",version,m_usuario.getRegion().getId()) + "}";
                log.debug("login:"+output);
            } else {
                output = "error=" + codError + ";";

                if ( codError == -50 && m_usuario != null ){

                    long f_actual = Calendar.getInstance().getTimeInMillis();
                    long f_admision = m_usuario.getfAdmision().getTime();

                    long millis = f_admision - f_actual;

                    output+="descripcion="+ (millis/1000);
                }
            }
            output += ";tProceso=" + (fin-ini);
            
            if ( aux_output.getCadena().length()>0 )
                output+=aux_output.getCadena();
            
            em.getTransaction().commit();
        } catch (Exception e) {
            log.error("[wsLogin]: " , e);
            output = "error=-10";
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            
            Util.anidadas( e, "[wsLogin]: ");
        } finally {
            try { em.close(); } catch (Exception e) { } 
        }

        try {

            PrintWriter out = response.getWriter();

            out.print(output);
        } catch (Exception e) {
            log.error("[wsLogin]: " , e);
        }
    }

    public void wsListaServicios(HttpServletRequest request, HttpServletResponse response) {
        String          output  = "";
        int             region  = 0;
        EntityManager   em      = null;
        try {
            em = emfBasket.createEntityManager();
            String tipo = request.getParameter("tipo");
            if ( request.getParameter("region")!= null ) {
                region = Integer.parseInt (request.getParameter("region"));
            }
            HttpSession miSesion = request.getSession(true);
            output+="servicios={" + listaServiciosRegion(em,tipo,0,region) + "}";

            PrintWriter out = response.getWriter();
            out.print(output);

        } catch (Exception e) {
            log.error("[wsListaServicios]: " , e);
        }
    }

    /*
     * Devuelve:
     *
     *  -1 => si se ha producido algún error no controlado (base de datos, etc.)
     *  -2 => si el usuario ya ha creado su número máximo de equipos
     *  -3 => si el nombre y nick del equipo ya existen
     *  -4 => si la sesión no es válida
     */
    public Equipo wsCrearEquipo(HttpServletRequest request, HttpServletResponse response) {

        Equipo  equipo = null;
        Boolean existe = false;
        //Boolean beta   = false;
        String  output = "";

        // "Hardcodeamos" las plantillas hasta nuevo aviso
        // 12-03-2012 Se fija este orden de forma definitiva
        Integer Plantillas[][] = {
            {16,6,14,17,31},  // 0 - Fox
            {20,22,8,17,15},  // 1 - Urban
            {20,23,24,13,31}, // 2 - Bright
            {16,22,24,12,3}   // 3 - Bastión
        };

        EntityManager em = null;

        log.info("crear equipo");

        try {

            int idPack = Integer.parseInt(request.getParameter("pack_id"));
            String nombre = URLDecoder.decode(request.getParameter("nombre"),"UTF-8");
            String nick   = URLDecoder.decode(request.getParameter("nick"),"UTF-8");
            
            String colores[] = {"", "", "", "", "", ""};
            HttpSession sesion = request.getSession();
            em = emfBasket.createEntityManager(); // check 07.08.2012
            int idUsuario = comprobarSesion(sesion.getId(),em);

log.debug("CREAR   EQUIPO PARAMETROS " + request.getParameter("nombre") + " y nick " + request.getParameter("nick") );
log.debug("DECODER EQUIPO PARAMETROS " + request.getParameter("nombre") + " y nick " + request.getParameter("nick") );

            if (idUsuario < 0) {
                output="error=-4;equipo_id=0";
            } else {
                log.info("Buscando usuario: " + idUsuario);
                Query q = em.createNamedQuery("Usuario.findById");
                q.setParameter("id", idUsuario);
                com.bitoon.basketdudes.jpa.Usuario u = (Usuario)q.getSingleResult();

                // Asignamos la zona al equipo
                // Si no hay zona como parametro elegimos la que tenga orden mayor
                int    zona;
                if ( request.getParameter("zona") == null  ) {
                    zona = -1;
                    Region region = u.getRegion();
                    Central central = new Central();
                    int region_id= u.getRegion().getId();

                    zona = central.zonaMayor(em, region_id, 1);
                } else {
                    zona = Integer.parseInt(URLDecoder.decode(request.getParameter("zona"),"UTF-8"));
                }
                
                log.info("Buscando equipos del usuario: " + idUsuario);
                q = em.createNamedQuery("Equipo.findByIdUsuario");
                q.setParameter("idUsuario", idUsuario);
                List<Equipo> l = (List<Equipo>)q.getResultList();

                if (l.size() >= MAX_EQUIPOS_POR_USUARIO) {
                    output="error=-2;equipo_id=0"; // No se pueden crear más equipos
                } else {
                    if ( existe == false ) {
                        // Comprobar si el nombre existe
                        q = em.createNamedQuery("Equipo.findByNombreYNick");
                        q.setParameter("nombre", nombre.toLowerCase());
                        q.setParameter("nick", nick.toLowerCase());

                        try {
                            Equipo be = (Equipo)q.getSingleResult();
                            existe = true;
                        } catch (NoResultException nre) { // No existe el equipo
                        }
                    }

                    if ( existe == false ) {
                        equipo = new Equipo();
                        equipo.setNombre(nombre);
                        equipo.setNombreUrl(dameNombreURL(nombre, nick));

                        log.info("nick del equipo: " + nick);

                        equipo.setNick(nick);
                        equipo.setCreditoTalento(0);
                        equipo.setEntrenadorId(0);
                        equipo.setPowerplay(0f);
                        equipo.setStatus(0);
                        // Cada equipo parte con 3000 dudies de credito
                        equipo.setPuntos(3000);

                        equipo.setUsuario(u);
                        equipo.setNivel((short)1);
                        equipo.setfUltimo(new Date());

                        equipo.setZonaId( zona );
                        
                        // Iniciamos la transacción
                        em.getTransaction().begin();

                        // Grabamos el equipo
                        em.persist(equipo);

                        EstEquipo est = new EstEquipo(equipo.getId(),u.getId());
                        em.persist(est);

                        // Guardo el aspecto
                        AspectoEquipo aspecto = new AspectoEquipo();
                        aspecto.setEquipoId	(equipo.getId());
                        aspecto.setCamiseta	(Short.parseShort(  request.getParameter("camiseta"     )));
                        aspecto.setPantalon	(Short.parseShort(  request.getParameter("pantalon"     )));
                        aspecto.setClr1		(                   request.getParameter("clr1" 	));
                        aspecto.setClr2		(                   request.getParameter("clr2" 	));
                        aspecto.setClr3		(                   request.getParameter("clr3" 	));
                        aspecto.setClr21	(                   request.getParameter("clr21" 	));
                        aspecto.setClr22	(                   request.getParameter("clr22" 	));
                        aspecto.setClr23	(                   request.getParameter("clr23" 	));
                        aspecto.setFont		(Short.parseShort(  request.getParameter("font" 	)));
                        aspecto.setFontClr	(                   request.getParameter("font_clr"     ));
                        aspecto.setFontEdge	(                   request.getParameter("font_edge"    ));
                        aspecto.setFront	(Short.parseShort(  request.getParameter("front" 	)));
                        aspecto.setBack		(Short.parseShort(  request.getParameter("back" 	)));
                        aspecto.setLogoimgId	(Short.parseShort(  request.getParameter("logoimg_id" 	)));
                        aspecto.setLogoimgClr1	(                   request.getParameter("logoimg_clr1"	));
                        aspecto.setLogoimgClr2	(                   request.getParameter("logoimg_clr2"	));
                        aspecto.setLogoimgClr3	(                   request.getParameter("logoimg_clr3"	));
                        aspecto.setLogoimgX	(Float.parseFloat(  request.getParameter("logoimg_x"	)));
                        aspecto.setLogoimgY	(Float.parseFloat(  request.getParameter("logoimg_y" 	)));
                        aspecto.setLogoimgAng	(Float.parseFloat(  request.getParameter("logoimg_ang" 	)));
                        aspecto.setLogoimgEsc	(Float.parseFloat(  request.getParameter("logoimg_esc" 	)));
                        aspecto.setLogotxtId	(Short.parseShort(  request.getParameter("logotxt_id" 	)));
                        aspecto.setLogotxtClr1	(                   request.getParameter("logotxt_clr1" ));
                        aspecto.setLogotxtClr2	(                   request.getParameter("logotxt_clr2" ));
                        aspecto.setLogotxtClr3	(                   request.getParameter("logotxt_clr3" ));
                        aspecto.setLogotxtX	(Float.parseFloat(  request.getParameter("logotxt_x" 	)));
                        aspecto.setLogotxtY	(Float.parseFloat(  request.getParameter("logotxt_y" 	)));
                        aspecto.setLogotxtAng	(Float.parseFloat(  request.getParameter("logotxt_ang" 	)));
                        aspecto.setLogotxtEsc	(Float.parseFloat(  request.getParameter("logotxt_esc" 	)));
                        aspecto.setBallId       (1);

                        em.persist(aspecto);

                        // Grabar los jugadores
                        MJugador jaux = null;
                        float sumaPowerPlay = 0;

                        for (int x=0; x<5; x++) {

                            q = em.createNamedQuery("MJugador.findById");
                            q.setParameter("id", Plantillas[idPack][x]);
                            jaux = (MJugador)q.getSingleResult();

                            Jugador j = new Jugador();
                            j = inicializarJugador(jaux);
                            j.setMJugador(jaux);
                            j.setEquipo(equipo);
                            j.setNivel((short)1);

                            em.persist(j);

                            sumaPowerPlay+=mediaJugador(j);

                            PlantillaPK ppk = new PlantillaPK(equipo.getId(), j.getId(), (short)(x+1));
                            Plantilla p = new Plantilla(ppk);
                            p.setTitular(TITULAR);
                            //p.setDemarcacion(j.getMJugador().getPosicion1());
                            p.setDemarcacion((short)(x+1));
                            em.persist(p);
                        }

                        Vestidor vestidor= new Vestidor();
                        vestidor.calcularPowerPlay ( em, equipo);
                        //equipo.setPowerplay(sumaPowerPlay);
                        em.persist(equipo);
                        em.getTransaction().commit();

                        output="error=0;equipo_id=" + equipo.getId();
                    } else {
                        // Existe el equipo
                        output = "error=-3;equipo_id=0";
                    }
                }
            }
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[wsCrearEquipo]: ", e);
            output="error=-1;equipo_id=0";
        } finally {
            try {
                PrintWriter out = response.getWriter();
                out.print(output);
            } catch (Exception e) {
                log.error("[wsCrearEquipo]: Error al escribir en response.getWriter()", e);
            }
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
            return equipo;
        }
    }

    private float mediaJugador(Jugador j) {
        float retorno = (float)0;

        int suma = j.getT1() + j.getT2() + j.getT3() + j.getAgresividad() +
                j.getDriblin() + j.getPase() + j.getReboteAtaque() +
                j.getReboteDefensa() + j.getDefensa() + j.getRobo() +
                j.getTapon() + j.getResistencia() + j.getVelocidad() +
                j.getSprint() + j.getTeamwork();

        log.info("La suma del jugador: " + j.getMJugador().getId() + " es " + suma);

        retorno = (float)suma/15;

        log.info("La media del jugador: " + j.getMJugador().getId() + " es " + retorno);

        return retorno;
    }

    public void wsComprobarSesionPartida(HttpServletRequest request, HttpServletResponse response, boolean p_check_partida) {
        int idUsuario = 0;
        EntityManager em = null;
        int idPartida = 0;
        int idEquipo = 0;
        XMLOutputter out = null;
        Document doc = null;
        Element root = new Element("checkSessionPartida");;
        Element datosPartida    = null;
        int     retorno         = -10;

        try {
            idPartida = Integer.parseInt(request.getParameter("idPartida"));
            idEquipo = Integer.parseInt(request.getParameter("idEquipo"));

            root = new Element("checkSesionPartida");
            datosPartida = new Element("datosPartida");

            em = emfBasket.createEntityManager(); // check 07.08.2012
log.debug("SESION RECIBIDA" + request.getSession().getId() +" chequear "+ p_check_partida);
            if ( p_check_partida && idPartida!=1 ) {
                idUsuario = comprobarSesion(request.getSession().getId(),em);
            } else {
                idUsuario=1;
            }

            if ( idPartida==1) {
                idUsuario=12;
            }

            if (idUsuario > 0) {

                /* Comprobamos si el equipo es del usuario */
                Query q2 = em.createNamedQuery("Equipo.findById");
                q2.setParameter("idEquipo", idEquipo);

                Equipo eq = (Equipo)q2.getSingleResult();

                if ( eq != null){
                    if ( eq.getUsuario().getId()== idUsuario ) {
                        Partida p = null;
                        Query q = em.createNamedQuery("Partida.findById");
                        q.setParameter("id", idPartida);
                        p = (Partida)q.getSingleResult();

                        if ( p != null){
                            if ( idEquipo==p.getEquipo1Id() || idEquipo ==p.getEquipo2Id()  ) {
                                // La informacion suministrada es correcta
                                datosPartida.setAttribute("partidaId", Integer.toString(p.getId()));
                                datosPartida.setAttribute("idEquipo1", Integer.toString(p.getEquipo1Id()));
                                datosPartida.setAttribute("idEquipo2", Integer.toString(p.getEquipo2Id()));
                                datosPartida.setAttribute("idUsuario", Integer.toString(eq.getUsuario().getId()));

                                /* 05/10/2011 Para los partido PVE recuperamos el identificador del usuario rival ya que
                                 * la validación de la sesión se hace para ambos al mismo tiempo en el servidor de juego
                                 */
                         
                                if ( p.getTipo() == 4 ) {
                                    Query eq2 = em.createNamedQuery("Equipo.findById");
                                    if ( idEquipo==p.getEquipo2Id() ){
                                        eq2.setParameter("idEquipo", p.getEquipo1Id() );
                                    } else {
                                        eq2.setParameter("idEquipo", p.getEquipo2Id() );
                                    }

                                    Equipo equipo2 = (Equipo)eq2.getSingleResult();
                                    datosPartida.setAttribute("idUsuario2", Integer.toString(equipo2.getUsuario().getId()));
log.debug(" USUARIO2 " + equipo2.getUsuario().getId());
                                }

                                datosPartida.setAttribute("tipo"     , Integer.toString(p.getTipo()));
                                datosPartida.setAttribute("tiempo"   , Integer.toString(p.getTiempo()));
                                /* 25/05/2011 Nuevo campo estado para que el servidor de juego compruebe
                                 * si la partida está Iniciada/Finalizada
                                 */
                                datosPartida.setAttribute("estado"   , Integer.toString(p.getEstado()));

                                root.addContent(datosPartida);

                                retorno = 0;
                                root.setAttribute("err", "0");

                                log.debug("[SESION_PARTIDA][CORRECTA]: " + Integer.toString(p.getPartidaId())+"-"+ p.getPartidaId() + " - " + idPartida+" eq: " + idEquipo + " usu: " + idUsuario);
                            }else{
                                // El equipo juega no este partido
                                retorno = -6;
                                log.debug("[ERROR][SESION_PARTIDA][EQUIPO]: " + idPartida+" eq: " + idEquipo + " usu: " + idUsuario);
                            }
                        } else {
                            // Partida no existe
                            retorno = -5;
                            log.debug("[ERROR][SESION_PARTIDA][PARTIDA INCORRECTA]: " + idPartida+" eq: " + idEquipo + " usu: " + idUsuario);
                        }
                    } else {
                        // El equipo no es del usuario que tiene la sesión
                        retorno = -4;
                        log.debug("[ERROR][SESION_PARTIDA][EQUIPO OTRO USUARIO]: " + idPartida+" eq: " + idEquipo + " usu: " + idUsuario);
                    }
                } else {
                    // El equipo no existe
                    retorno = -2;
                    log.debug("[ERROR][SESION_PARTIDA][EQUIPO NO EXISTE]: " + idPartida+" eq: " + idEquipo + " usu: " + idUsuario);
                }
            } else {
                // La sesión no es válida
                retorno = -3;
                log.debug("[ERROR][SESION_PARTIDA][SESION]: " + idPartida+" eq: " + idEquipo + " usu: " + idUsuario + " ses: " + request.getSession());
            }
        } catch (Exception e) {
            log.error("[ERROR][wsComprobarSesionPartida]: ", e);
            retorno = -1;
        } finally {
            try {
                doc = new Document(root);
                doc.setDocType(null);
                out = new XMLOutputter();

                if (retorno<0) {
                    response.getWriter().print(retorno);
                } else {
                    response.getWriter().print(out.outputString(doc));
                }
            } catch (Exception e) { };
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
    }

    public void wsDamePlantilla(HttpServletRequest request, HttpServletResponse response) {
        int idEquipo = 0;
        String output = "";
        EntityManager em = null;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            idEquipo = Integer.parseInt(request.getParameter("idEquipo"));

            Query q = em.createNamedQuery("Plantilla.findByEquipoId");
            q.setParameter("equipoId", idEquipo);
            List<Plantilla> l = q.getResultList();

            int nJugadores = 0;
            String plantilla = "";
            for(Plantilla p : l) {
                nJugadores++;
                plantilla += "|" + p.getPlantillaPK().getJugadorId();

                /* HACK para ir regenerando las posiciones */
                if (p.getDemarcacion() != nJugadores)
                    p.setDemarcacion((short)nJugadores);
                /* HACK para ir regenerando la titularidad */
                if ( p.getTitular() == 1 && nJugadores>5 )
                    p.setTitular(SUPLENTE);
                if ( p.getTitular() == 0 && nJugadores<5 )
                    p.setTitular(TITULAR);

            }
            if (nJugadores>=5) {
                output = "0" + plantilla;
            }

        } catch (Exception e) {
            output = "-1";
            log.error("[ERROR][wsDamePlantilla]: ", e);
        } finally {
            try { response.getWriter().print(output); } catch (Exception e) { };
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

    }

    public void wsAsignarTalento(HttpServletRequest request, HttpServletResponse response) {

        EntityManager em = null;
        String output = "";

        // Parámetros de entrada
        int idJugador = 0;
        int idTalento = 0;
        int aux_usuario_id;

        try {

            idJugador = Integer.parseInt(request.getParameter("idJugador"));
            idTalento = Integer.parseInt(request.getParameter("idTalento"));

            HttpSession miSesion    = request.getSession(true);
            String      sesion_id   = miSesion.getId();
            log.info("--------------");
            log.info(" jugador " + idJugador + " talento " + idTalento + " s:" + sesion_id);

            em = emfBasket.createEntityManager(); // check 07.08.2012
            Jugador j = em.find(Jugador.class, idJugador);
            Equipo e = j.getEquipo();

            //LoginAction la = new LoginAction();
            aux_usuario_id = comprobarSesionEquipo(sesion_id,e.getId(),em);
            if ( aux_usuario_id <0 ) {
                output="error=-10;descripcion=Sesion Incorrecta";
            } else {
                em.getTransaction().begin();

                /* recuperamos el talento */
                Query qt = em.createNamedQuery("Talento.findById");
                qt.setParameter("id"   , (short)idTalento);

                List<Talento> lista_talento = qt.getResultList();
                if ( lista_talento == null || lista_talento.isEmpty() ) {
                    throw new ExcepcionGeneral( -6, "Talento no existe " + idTalento );
                }
                Talento talento = lista_talento.get(0);

    log.info("equipo : " + e.getId() + " credito " + e.getCreditoTalento());

                if (e.getCreditoTalento()>= talento.getCoste() ) {

                    // hasta el 15 de noviembre - 1 es que se puede asignar
                    // 15 noviembre - 0 es que se puede asignar
                    // continuará ...

    log.info("jugador_id : " +j.getMJugador().getId() + " talento_id " + idTalento);

                    Query q = em.createNativeQuery(
    "select t.* from cat_talento_m_jugador tm, talento t, categoria c where tm.cat_talento = c.id and t.categoria_id = c.id and tm.modelo_id = ? and t.id = ? and t.estado = 0", Talento.class);
                    q.setParameter(1,j.getMJugador().getId());
                    q.setParameter(2,idTalento);

                    List l = q.getResultList();

    log.info("Resultado : " + l.size() );

                    if (l.size() > 0) {
                        // El talento se puede asignar

                        output = "error=0;";

                        boolean talentoAsignado = true;

                        log.info("jugador j: " + j);

                        Short tal1 = (j.getTalento1() == null ? 0 : j.getTalento1() );
                        Short tal2 = (j.getTalento2() == null ? 0 : j.getTalento2() );
                        Short tal3 = (j.getTalento3() == null ? 0 : j.getTalento3() );

                        log.info("tal1: " + tal1);

                        if ( (tal1!=idTalento) && (tal2!=idTalento) && (tal3!=idTalento) ) {
                            // El talento no está asignado
                            if (tal1<=0) {
                                j.setTalento1((short)idTalento);
                                output+="slot=1";
                            } else if (tal2<=0) {
                                j.setTalento2((short)idTalento);
                                output+="slot=2";
                            } else if (tal3<=0) {
                                j.setTalento3((short)idTalento);
                                output+="slot=3";
                            } else {
                                output = "error=-3;descripcion=Todos los talentos ocupados";
                                talentoAsignado = false;
                            }
                        } else {
                            output = "error=-4;descripcion=El talento ya está asignado";
                            talentoAsignado = false;
                        }

                        if (talentoAsignado) {
                            e.setCreditoTalento(e.getCreditoTalento()-talento.getCoste()  );
    log.debug(" Credito Equipo " +e.getCreditoTalento()+ " Coste " + talento.getCoste());
                            em.persist(j);
                            em.persist(e);
                        }
                    } else {
                        log.error("Talento " +idTalento+"no asignable a m_jugador_id : " +j.getMJugador().getId() );
                        output = "error=-2;descripcion=Talento no asignable";
                    }

                    em.getTransaction().commit();
                    output += ";puntos="+e.getCreditoTalento();

                } else {
                    // No hay creditos
                    output = "error=-5;descripcion=El equipo no tiene puntos de talento";
                    if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
                }
            }
        } catch (ExcepcionGeneral nre) {
            output = "error="+nre.getCodigo()+";descripcion="+nre.getDescripion();
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } catch (NoResultException nre) {
            // El talento no se puede asignar al jugador
            output = "error=-2;descripcion=Talento no asignable";
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } catch (Exception e) {
            output = "error=-1";
            log.error("Error general", e);
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();

        } finally {
            try { response.getWriter().print(output); } catch (Exception e) { };
            try { if (em.getTransaction().isActive()) { em.getTransaction().commit(); } } catch (Exception e) { }
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
    }

    public void wsGrabarPlantilla(HttpServletRequest request, HttpServletResponse response) {

        EntityManager em = null;
        String output = "";

        // Parámetros de entrada
        int idEquipo;
        int[] posicion = new int[5];

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            idEquipo = Integer.parseInt(request.getParameter("idEquipo"));

            HttpSession miSesion    = request.getSession(true);
            String      sesion_id   = miSesion.getId();
            log.info("--------------");

            int usuario_id = comprobarSesionEquipo(sesion_id,idEquipo,em);
            if ( usuario_id <0 ) {
                output="error=-10;descripcion=Sesion Incorrecta";
            } else {
                em.getTransaction().begin();
                Query q = em.createNamedQuery("Plantilla.findByEquipoId");
                q.setParameter("equipoId", idEquipo);
                List<Plantilla> lista = q.getResultList();
                int total_plantilla = lista.size();

                log.info("Equipo: "     + idEquipo + " total: "+ total_plantilla);
                for (int x=1; x<=total_plantilla; x++) {
                    if (request.getParameter("pos"+x) != null) {
                        int idJugador = Integer.parseInt(request.getParameter("pos"+x));

                        log.info("Parametro " +"pos"+x+": " +  idJugador);

                        /* Buscamos al jugador en la plantilla y asignamos la nueva posicion */
                        boolean encontrado=false;
                        for (int y=0; y<total_plantilla; y++) {
                            Plantilla   plan    = (Plantilla)lista.get(y);
                            PlantillaPK plan_pk = plan.getPlantillaPK();

                            if ( plan_pk.getJugadorId()==idJugador ) {
                                encontrado= true;
                                plan.setDemarcacion((short)x);
                                if (x<=5) { // Titular
                                    plan.setTitular(TITULAR);
                                } else {
                                    plan.setTitular(SUPLENTE);
                                }
                                em.persist(plan);
                            }
                        }
                    } else {
                        throw new ExcepcionGeneral( -2, "falta información");
                    }
                }
                em.getTransaction().commit();

                output="error=0";
            }
        } catch (ExcepcionGeneral nre) {
            output = "error=-2;descripcion=No se encontró algún jugador/demarcación";
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } catch (Exception e) {
            output = "error=-1";
            log.error("Error general", e);
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } finally {
            try { response.getWriter().print(output); } catch (Exception e) { };
            try { if (em.getTransaction().isActive()) { em.getTransaction().commit(); } } catch (Exception e) { }
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

    }

    public void wsUploadLogo(HttpServletRequest request, HttpServletResponse response) {

        String output = "error=-1";
        final String FIELD_EQUIPOID ="teamid";

        try {

            // Usar jakarta commons fileupload
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);

            if (isMultipart) {
                FileItemFactory factory = new DiskFileItemFactory();
                ServletFileUpload upload = new ServletFileUpload(factory);

                //ArrayList items = new ArrayList();
                //items = (ArrayList)upload.parseRequest(request);
                List items = upload.parseRequest(request);
                Iterator iter = items.iterator();

                int     idEquipo = 0;
                String  nombre_fichero="";

                while (iter.hasNext()) {
                    FileItem item = (FileItem)iter.next();

                    log.debug("item: " + item);
                    log.debug("isFormField? " + item.isFormField());

                    if (item.isFormField()) {
                        if (item.getFieldName().equalsIgnoreCase(FIELD_EQUIPOID)) {
                            idEquipo = Integer.parseInt(item.getString());
                        }
                    } else { // Fichero
                        if (idEquipo > 0) {
                            if ( item.getName().equalsIgnoreCase("icon.png") )
                                nombre_fichero=dameFicheroIcono(idEquipo);
                            else
                                nombre_fichero=dameFicheroLogo(idEquipo);
log.debug("UPLOAD NOMBRE FICHERO " + item.getName() +" - "+nombre_fichero);
                            try {
                                File fichero = new File(nombre_fichero);
                                item.write(fichero);
                            } catch ( java.io.FileNotFoundException fne2) {
                                // Creamos el directorio de segundo nivel
                                String fich2 = dameFichero(idEquipo, "", 2 );
log.debug("NO EXISTE EL DIRECTORIO " + fich2);
                                File fichero2 = new File(fich2);
                                fichero2.mkdirs();

                                File fichero = new File(nombre_fichero);
                                item.write(fichero);
                            }
                            output="error=0";
                        } else {
                            output="error=-2";
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("Error upload: " , e);
            output="error=-3";
        } finally {
            try {
                PrintWriter out = response.getWriter();
                out.print(output);
            } catch (Exception e) {
                log.error("Error upload: " , e);
            }
        }
    }

    // Devuelve el nombre del fichero del logo
    private String dameFicheroLogo(int idUsuario) {
        return dameFichero(idUsuario, "", 3);
    }
    // Devuelve el nombre del fichero de icono
    private String dameFicheroIcono(int idUsuario) {
        return dameFichero(idUsuario, "i", 3);
    }

    private String dameFichero(int idUsuario, String sufijo, int nivel) {
        String retorno = privatePath;

        DecimalFormat f1 = new DecimalFormat("00");
        DecimalFormat f2 = new DecimalFormat("00000");
        int n1 = idUsuario/1000000;
        int n2 = (idUsuario-n1*1000000)/10000;
        int n3 = (idUsuario-n1*1000000-n2*10000);

        retorno += "/" + f1.format(n1);
        if ( nivel == 1)
            return retorno;
        retorno += "/" + f1.format(n2);
        if ( nivel == 2)
            return retorno;
        retorno += "/" + f2.format(n3) + sufijo + ".png";

        return retorno;
    }

    public Jugador inicializarJugador(MJugador jaux) {
        Jugador retorno = new Jugador();

        retorno.setFAlta(new Date());
        retorno.setFAlta(new Date());
        retorno.setPrecioCompra(0);
        retorno.setPuntosCompra(0);
        retorno.setValoracion((float)0);

        retorno.ResetRopa();

        retorno.setBT1(jaux.getT1());
        retorno.setBT2(jaux.getT2());
        retorno.setBT3(jaux.getT3());
        retorno.setBAgresividad(jaux.getAgresividad());
        retorno.setBDriblin(jaux.getDriblin());
        retorno.setBPase(jaux.getPase());
        retorno.setBReboteAtaque(jaux.getReboteAtaque());
        retorno.setBDefensa(jaux.getDefensa());
        retorno.setBRobo(jaux.getRobo());
        retorno.setBTapon(jaux.getTapon());
        retorno.setBReboteDefensa(jaux.getReboteDefensa());
        retorno.setBResistencia(jaux.getResistencia());
        retorno.setBVelocidad(jaux.getVelocidad());
        retorno.setBTeamwork(jaux.getTeamwork());
        retorno.setBSprint(jaux.getSprint());

        float valoracion = (jaux.getT1() +
            jaux.getT2() +
            jaux.getT3() +
            jaux.getAgresividad() +
            jaux.getDriblin() +
            jaux.getPase() +
            jaux.getReboteAtaque() +
            jaux.getDefensa() +
            jaux.getRobo() +
            jaux.getTapon() +
            jaux.getReboteDefensa() +
            jaux.getResistencia() +
            jaux.getVelocidad() +
            jaux.getTeamwork() +
            jaux.getSprint()) / 15f;

        retorno.setValoracion(valoracion);

        return retorno;
    }

    public boolean sesionValida(HttpSession sesion) {
        boolean retorno = false;
        try {
            if (sesion.getAttribute("activo") != null) {
                if ( (Boolean)sesion.getAttribute("activo") ) {
                    retorno = true;
                }
            } else {

            }
        } catch (Exception e) {
            log.error("[ERROR][sesionValida]: " , e);
        }

        return retorno;
    }

    // Posibles retornos
    // -2: error indeterminado
    // -3: nick o contraseña incorrecta
    //
    // -9: Registro necesario
    // -50: baneado temporalmente
    // -20: baneado para siempre
    
    public int comprobarLogin(String p_nick, String p_password, int p_servicio_id, int partner_id, 
                              OutString aux_retorno, HttpServletRequest p_request) {

        int retorno      = -1;
        EntityManager em = null;
        Usuario u        = null;
        String  nick     = null;
        aux_retorno.setCadena("");

        try {
            em = emfBasket.createEntityManager(); 
            nick= p_nick.toLowerCase().trim();
            
            try {
                Query q = em.createNamedQuery("Usuario.findByNickPassword");

                q.setParameter("nick", nick);
                q.setParameter("password", p_password);
                u = (Usuario)q.getSingleResult();

            } catch ( NoResultException nores) {
                // Si está activa la gestión de usuarios de marca.com
                // y la contraseña parece venir en claro por tener una longitud < 40
                // intentamos el login contra dicha plataforma
                if ( conf.BuscarValorConfiguracionInteger( "marca.com" )>0 && u==null ) {
                    MarcaUser mu=null;
                    try {
                        Query qv = em.createNamedQuery("MarcaUser.findByNick");
                        qv.setParameter("nick",  nick );

                        mu = (MarcaUser)qv.getSingleResult();
                    } catch(NoResultException e) {
                        // para que no salte la excepción
                    }
                    if ( mu != null ) {
                        if ( p_password.length()<40 ) {
                            log.debug("[DEBUG][MARCA ACTIVADO]: " + nick);
                            MarcaCom marca= new MarcaCom();
                            u = marca.login( em, nick, p_password );
                        } else {
                            if ( !mu.getPassword().isEmpty() && mu.getPassword().compareTo(p_password)== 0 ) {
                                u = mu.getUsuario();
log.debug("[LOGIN MARCA BD OK]: " + u.getNick() );
                            } else {
log.debug("[LOGIN MARCA BD KO]: " + mu.getNick() +" encriptada: " + mu.getPassword() + " param: " + p_password );
                            }
                        }
                    } else {
log.debug("[LOGIN MARCA USUARIO NO EXISTE]: " + nick);
                    }

                }
                // Si no hay usuario validado, arkarena está activo en la configuración
                // y el nick contiene una @ de un email interrogamos al login de Arkarena
                if ( partner_id == 2    &&
                     nick.contains("@") &&
                     conf.BuscarValorConfiguracionInteger( "arkarena" )>0 && u==null ) {
                    String p_nick_remoto="";
log.debug("[LOGIN ARKARENA]: " + nick );                    
                    em.getTransaction().begin(); 
                    try {
                        Arkarena arkarena = new Arkarena();
                        retorno = arkarena.login ( em, nick, p_password, 
                                conf.BuscarValorConfiguracionString( "arkarena.ruta" ), p_request );
                        if ( retorno == -9) {
                            aux_retorno.setCadena( aux_retorno.getCadena() + ";nick_remoto="+arkarena.getNickRemoto()+";");
                        } 
                        if ( retorno == 0 ) {
                            u = arkarena.getUsuarioLogado();
                        }
                        em.getTransaction().commit();                    
                    } catch (Exception e) {
                        try { em.getTransaction().rollback(); } catch (Exception e2) { }
                    }
                }
                if ( retorno != -9 && retorno != -10) {
                    if ( u==null ) {
                        log.debug("[ERROR][nick o passwd incorrecto]: " + nick + "[passwd]" + p_password);
                        retorno = -3;
                    }
                }
            }

            if (u != null) { // El usuario es válido
log.debug("[DEBUG][USUARIO ENCONTRADO]: " + u.getNick());
                if ( u.getStatus()== 0 || u.getStatus()==1 )
                {
                    retorno = u.getId();
                    m_usuario = u;

                    if ( u.getfAdmision().getTime() > new Date(System.currentTimeMillis()).getTime()  )
                    {
                        /* Usuario baneado temporalmente */
                        retorno = -50; // cuenta baneada
log.debug("[DEBUG][BANEO TEMPORAL]: " + u.getNick());
                    } else {
                        // Actualizamos la fecha del último login
                        em.getTransaction().begin();
                        u.setfUltimo(new Date(System.currentTimeMillis()));

                        // 08/11/2011
                        // Actualizamos las visitas realizadas y la fecha de la
                        // ultima visita por el usuario al servicio
                        Query qv = em.createNamedQuery("Visita.findByUsuarioId");

                        qv.setParameter("usuario_id",  u.getId());
                        qv.setParameter("servicio_id", (short)p_servicio_id );
                        Visita v = null;
                        try {
                            v = (Visita)qv.getSingleResult();

                            v.setTotal( (short) (v.getTotal() + 1) );
                            v.setFUltimo( new Date() );
                        } catch (NoResultException nre) {
                            v    = new Visita ();
                            VisitaPK pk_v = new VisitaPK();

                            pk_v.setUsuarioId(u.getId());
                            pk_v.setServicioId((short)p_servicio_id);

                            v.setFUltimo(new Date());
                            v.setTotal((short)1);
                            v.setUsuario(u);
                            v.setVisitaPK(pk_v);
                        }
                        em.persist( v );
                        em.persist( u );
                        

                        // 07/08/2012 Buscamos primero la h_visita del día para no provocar
                        // errores molestos por el log
                        HVisita h_v = null;
                        Query qhv = em.createNamedQuery("HVisita.findByFecha");

                        qhv.setParameter("usuario_id"    , u.getId());
                        qhv.setParameter("servicio_id"   , (short)p_servicio_id);
                        qhv.setParameter("fecha"         , new Date());
                        try {
                            h_v = (HVisita)qhv.getSingleResult();

                        } catch (NoResultException nre) {
                            try {
                                h_v      = new HVisita ();
                                HVisitaPK h_pk_v = new HVisitaPK();

                                h_pk_v.setFecha(new Date());
                                h_pk_v.setUsuarioId(u.getId());
                                h_pk_v.setServicioId((short)p_servicio_id);
                                h_v.setHVisitaPK(h_pk_v);
                                em.persist ( h_v );
                            } catch (Exception dk) {
                                log.debug(dk);
                            }
                        }

                        em.getTransaction().commit();
                    }
                } else {
                    // 02/11/2011 Ahora se permite pasar a los usuarios que no han confirmado email
                    // Antiguo retorno cuando el estado era 0
                    //retorno = -10; // cuenta inactiva

                   retorno = -20; // cuenta baneada
                }
            
                aux_retorno.setCadena( aux_retorno.getCadena()+
                        ";par="+u.getRegion().getPartner().getId()+
                        ";src="+u.getOrigenId() );                
            }
        } catch (Exception e) {
            if (log.isDebugEnabled()) {
                    log.error("[ERROR][comprobarLogin]: ", e);
            }
            retorno = -2;
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return retorno;
    }
/*
 * SUSTITUIDA POR LISTASERVICIOSREGION
 * 
    public String listaServicios(String tipo, int version) {

        String retorno = "";
        EntityManager em = null;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            Query q = em.createNamedQuery("Servicio.buscarTipo");
            q.setParameter("tipo", tipo.toLowerCase());
            List<Servicio> l = (List<Servicio>)q.getResultList();

            for(Servicio s : l) {
                if ( version < 4000 ) {
                    retorno+=","+s.getIp()+":"+s.getPuerto()+"|"+s.getZonaId()+":"+s.getNombre();
                } else {
                    retorno+=","+s.getIp()+":"+s.getPuerto()+"|"+s.getZonaId()+":"+s.getNombre()+":"+s.getTotal()+":"+s.getLibre();
                }
            }

            if (retorno.length()>0) {
               retorno = retorno.substring(1);
            }

        } catch (Exception e) {
            log.error("[ERROR][listaServicios]: ", e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return retorno;
    }
*/
    
    // 21-01-2013 Añadimos restricción de búsqueda por región si la condición region_lobby está 
    // activa en el config.properties
    public String listaServiciosRegion(EntityManager em, String tipo, int version, int p_region) {
        String retorno = "";

        try {
            Query q = null;
            // Si pasamos la region a 0 se buscarán todos los servicios de todas las zonas
            if ( conf.BuscarValorConfiguracionInteger("region_lobby") != 0 && p_region != 999 ) {
                q = em.createNamedQuery("Servicio.buscarTipoRegion");                
                q.setParameter("tipo", tipo.toLowerCase());
                q.setParameter("region_id", p_region );
            } else {
                q = em.createNamedQuery("Servicio.buscarTipo");                
                q.setParameter("tipo", tipo.toLowerCase());
            }
            
            List<Servicio> l = (List<Servicio>)q.getResultList();
            for(Servicio s : l) {
                    retorno+=","+s.getIp()+":"+s.getPuerto()+"|"+s.getZonaId()+":"+s.getNombre()+":"+s.getTotal()+":"+s.getLibre();
            }

            if (retorno.length()>0) {
               retorno = retorno.substring(1);
            }

        } catch (Exception e) {
            log.error("[ERROR][listaServiciosRegion]: ", e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return retorno;
    }
    

    
    
    public Servicio dameServidorJuego( EntityManager p_em, int p_zona ) {

        String retorno = "";
        EntityManager em = p_em;
        Servicio servicio = null;

        try {

            Query q = em.createNamedQuery("Servicio.buscarTipoZona");
            q.setParameter("tipo", "bd_game");
            q.setParameter("zona", p_zona );

            List<Servicio> l = (List<Servicio>)q.getResultList();

            if ( l.size()>0) {
                int tirada = (int)(Math.random()*l.size());

                servicio = l.get(tirada);
log.debug(" Encontrado Servicio bd_game posicion "+ tirada );
            } else {
log.debug(" NINGUN SERVICIO LIBRE tipo bd_game zona" + p_zona);
            }
        } catch (Exception e) {
            log.error("[ERROR][dameServidorJuego]: ", e);
        } finally {
            try { } catch (Exception e) { }
        }

        return servicio;
    }
/*
    public Equipo dameEquipo(int idEquipo) {

        Equipo retorno = null;
        EntityManager em = null;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            Query q = em.createNamedQuery("Equipo.findById");
            q.setParameter("idEquipo", idEquipo);
            Equipo e = (Equipo)q.getSingleResult();

            if (e != null) { // El equipo no es válido
                retorno = e;
            }
        } catch (Exception e) {
            log.error("[ERROR][dameEquipo]: "+idEquipo, e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return retorno;
    }

    public Usuario dameUsuario(int p_id) {

        Usuario retorno = null;
        EntityManager em = null;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            Query q = em.createNamedQuery("Usuario.findById");
            q.setParameter("id", p_id);
            Usuario e = (Usuario)q.getSingleResult();

            if (e != null) { // El usuario no existe
                retorno = e;
            }
        } catch (Exception e) {
            log.error("[ERROR][dameUsuario]: "+p_id, e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return retorno;
    }
*/
    public Equipo dameEquipo(int idEquipo, EntityManager p_em) {

        Equipo retorno = null;
        EntityManager   em      = p_em;
        try {
            if ( p_em == null )
                em = emfBasket.createEntityManager(); // check 08.08.2012

            Query q = em.createNamedQuery("Equipo.findById");
            q.setParameter("idEquipo", idEquipo);
            Equipo e = (Equipo)q.getSingleResult();

            if (e != null) { // El equipo no es válido
                retorno = e;
            }
        } catch (Exception e) {
            log.error("[ERROR][dameEquipo]: "+idEquipo, e);
        } finally {
            if ( p_em == null ) try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }


        return retorno;
    }

    public Usuario dameUsuario(int p_id, EntityManager p_em) {

        Usuario         retorno = null;
        EntityManager   em      = p_em;
        try {
            if ( p_em == null )
                em = emfBasket.createEntityManager(); // check 08.08.2012

            Query q = em.createNamedQuery("Usuario.findById");
            q.setParameter("id", p_id);
            Usuario e = (Usuario)q.getSingleResult();

            if (e != null) { // El usuario no existe
                retorno = e;
            }
        } catch (Exception e) {
            log.error("[ERROR][dameUsuario]: "+p_id, e);
        } finally {
            if ( p_em == null ) try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return retorno;
    }

    /*
     * Devuelve
     * equipos={x,x}&equiposNivel={x,x}&equiposPowerplay={x,x}&equiposPosicion={x,x}
     */
    public String dameInfoLogin(int idUsuario) {
        String retorno      = "";
        String equiposId    = "";
        String equiposNombre= "";
        String nivel        = "";
        String powerplay    = "";
        String posicion     = "";
        String datosUsuario = "";
        String logosId      = "";
        String ganados      = "";
        String jugados      = "";

        EntityManager em = null;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            Query q = em.createNamedQuery("Usuario.findById");
            q.setParameter("id", idUsuario);
            Usuario u = (Usuario)q.getSingleResult();

            // Grabar temporalmente en un xml la info del usuario
            //grabarUsuarioXML(u);

            // Leemos el xml
            //Usuario uxml = leerUsuarioXML(u.getId());

            datosUsuario = "idUsuario=" + u.getId() + ";";
            datosUsuario += "nickUsuario=" + u.getNickMostrar() + ";";
            datosUsuario += "reputacionUsuario="+u.getReputacion()+";";
            float c = u.getCreditos();
            datosUsuario += "bitoones=" + (int)c + ";";

            q = em.createNamedQuery("Equipo.findByIdUsuario");
            q.setParameter("idUsuario", idUsuario);

            List<Equipo> l = (List<Equipo>)q.getResultList();
            for(Equipo e : l) {
                equiposId+=","+e.getId();
                equiposNombre+=","+e.getNombre()+" " +e.getNick();
                nivel+=","+e.getNivel();
                powerplay+=","+e.getPowerplay();

                Ranking ranking = em.find(Ranking.class, e.getId());
                int pos = 0;
                if (ranking != null )
                    pos = ranking.getPosicion();

                posicion+=","+pos; // Cambiar por posicion real

                AspectoEquipo ae = em.find(AspectoEquipo.class, e.getId());
                logosId+=","+ae.getLogoimgId();

                EstEquipo     est_equipo = em.find(EstEquipo.class, e.getId());
                if (est_equipo != null ) {
                    ganados+=","+est_equipo.getGanados();
                    jugados+=","+(est_equipo.getGanados()+est_equipo.getPerdidos());
                } else {
                    ganados+=",0";
                    jugados+=",0";
                }
            }

            if (l.size() > 0) {
                equiposId = equiposId.substring(1);
                equiposNombre = equiposNombre.substring(1);
                nivel = nivel.substring(1);
                powerplay = powerplay.substring(1);
                posicion = posicion.substring(1);
                logosId = logosId.substring(1);
                ganados = ganados.substring(1);
                jugados = jugados.substring(1);
            }

        } catch (Exception e) {
            log.error("[ERROR][dameInfoLogin]: " , e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        retorno = datosUsuario
                + "equipos={" + equiposId + "};"
                + "equiposNombre={" + equiposNombre + "};"
                + "equiposNivel={" + nivel + "};"
                + "equiposPowerplay={" + powerplay + "};"
                + "equiposPosicion={" + posicion + "};"
                + "logosId={" + logosId + "};"
                + "ganados={" + ganados + "};"
                + "jugados={" + jugados + "}" ;

        return retorno;
    }

    /*
    public void grabarUsuarioXML(Usuario u) {
        try {

            Element root = new Element("Usuario");
            //root.setText("Hello JDOM!");

            root.setAttribute("lm", String.valueOf(new GregorianCalendar().getTimeInMillis()));
            root.addContent(new Element("nick").setText(u.getNick()));
            root.addContent(new Element("email").setText(u.getEmail()));

            Document doc = new Document(root);

            //FileWriter writer = new FileWriter("/home/webdev/" + u.getId() + ".xml", true);
            File f = new File("/home/webdev/" + u.getId() + ".xml");
            FileOutputStream writer = new FileOutputStream(f);
            XMLOutputter outxml = new XMLOutputter();
            outxml.output(doc, writer);
            writer.close();
        } catch (Exception e) {
            log.error("[grabaUsuarioXML] Error al grabar el XML: " , e);
        }
    }

    public Usuario leerUsuarioXML(int idUsuario) {

        Usuario u = null;

        try {
            SAXBuilder parser = new SAXBuilder();
            File f = new File("/home/webdev/" + idUsuario + ".xml");
            Document doc = parser.build(f);

            u = new Usuario();

            Element root = doc.getRootElement();
            Long lastModified = Long.parseLong(root.getAttributeValue("lm"));
            if (log.isDebugEnabled()) {
                log.debug("lm: " + lastModified);
            }
            u.setNick(root.getChild("nick").getText());
            u.setEmail(root.getChild("email").getText());

        } catch (Exception e) {
            log.error("[leerUsuarioXML]: " , e);
        }

        return u;

    }
     *
     */

    public void crearServicio(HttpServletRequest p_request, HttpServletResponse p_response) throws InterruptedException {

        EntityManager em = null;
        String ip       = null;
        int puerto      = 0;
        String tipo     = "";
        int conectados  = 0;
        int max_conex   = 0;
        int zona_id     = 0;
        String nombre   = "";

        try {
            ip          = p_request.getParameter                 ("ip");
            puerto      = Integer.parseInt(p_request.getParameter("puerto"));
            max_conex   = Integer.parseInt(p_request.getParameter("max_conex"));
            conectados  = Integer.parseInt(p_request.getParameter("conectados"));
            tipo        = p_request.getParameter                 ("tipo");
            zona_id     = Integer.parseInt(p_request.getParameter("zona_id"));
            nombre      = p_request.getParameter                 ("nombre");

            em = emfBasket.createEntityManager(); // check 07.08.2012

            Query q = em.createNamedQuery("Servicio.buscarIpPuerto");
            q.setParameter("ip", ip);
            q.setParameter("puerto", puerto);
            try {
                Servicio sb = (Servicio)q.getSingleResult();
log.info("[Keep Alive Servicio encontrado]: "+sb.getIp()+" p:"+sb.getPuerto()+" "+sb.getStatus());
                sb.setIp(ip);
                sb.setPuerto(puerto);
                sb.setTipo(tipo);
                sb.setLibre(max_conex-conectados);
                if ( max_conex > 0 )
                    sb.setTotal(max_conex);
                sb.setFechaUltimoPing(new java.util.Date());
                //sb.setFechaAlta( new java.util.Date() );
                sb.setZonaId(zona_id);
                sb.setNombre(nombre);

                em.getTransaction().begin();
                em.persist(sb);
                em.getTransaction().commit();
            } catch (NoResultException e) {
                Servicio s = new Servicio();
                s.setIp(ip);
                s.setPuerto(puerto);
                s.setTipo(tipo);
                s.setLibre(max_conex-conectados);
                s.setTotal(max_conex);
                s.setZonaId(zona_id);
                s.setNombre(nombre);
                

                em.getTransaction().begin();
                em.persist(s);
                em.getTransaction().commit();
            }
        } catch (Exception e) {
            log.error("[ERROR][crearServicio]: ", e);            
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
// OJO PRUEBAS

//        Thread.sleep(30000);

// OJO PRUEBAS

    }

    public void wsBajaServicio(String ip, int puerto, String tipo) {

        EntityManager em = null;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            Query q = em.createNamedQuery("Servicio.buscarIpPuertoTipo");
            q.setParameter("ip", ip);
            q.setParameter("puerto", puerto);
            q.setParameter("tipo", tipo);
            Servicio s = (Servicio)q.getSingleResult();

            em.getTransaction().begin();
            em.remove(s);
            em.getTransaction().commit();
        } catch (Exception e) {
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
            log.error("[ERROR][bajaServicio]: ",e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

    }

    public void wsRefrescaCuarto (int p_id, int p_cuarto, int p_tanteo1, int p_tanteo2) {
    // Actualiza el tanteo parcial de un partido

        EntityManager em = null;
        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012
            em.getTransaction().begin();

            Query q = em.createNamedQuery("Partida.findById");
            q.setParameter("id", p_id);

            Partida partida = (Partida)q.getSingleResult();
            partida.setEstado(1);
            partida.setCuartoJuego(p_cuarto);
            partida.setPuntosEquipo1(p_tanteo1);
            partida.setPuntosEquipo2(p_tanteo2);

            switch ( p_cuarto ) {
                case 0:
                    partida.setT11(0);partida.setT12(0);partida.setT13(0);partida.setT14(0);
                    partida.setT21(0);partida.setT22(0);partida.setT23(0);partida.setT24(0);
                    break;
                case 1:
                    partida.setT11(p_tanteo1);
                    partida.setT21(p_tanteo2);
                    break;
                case 2:
                    partida.setT12(p_tanteo1 - partida.getT11());
                    partida.setT22(p_tanteo2 - partida.getT21());
                    break;
                case 3:
                    partida.setT13(p_tanteo1 - partida.getT11() - partida.getT12());
                    partida.setT23(p_tanteo2 - partida.getT21() - partida.getT22());
                    break;
                case 4:
                    partida.setT14(p_tanteo1 - partida.getT11() - partida.getT12() - partida.getT13());
                    partida.setT24(p_tanteo2 - partida.getT21() - partida.getT22() - partida.getT23());
                    break;
            }

            em.getTransaction().commit();
        } catch (NoResultException e) {
            log.error("[ERROR][Partida no encontrada]: ", e);
        } catch (Exception e) {
            log.error("[ERROR][crearServicio]: ", e);
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
    }


    public void wsEstadisticas(HttpServletRequest request, HttpServletResponse response) {
        int idEquipo;
        String output = "";
        EntityManager em = null;
        XMLOutputter xmlOut = null;
        Document doc = null;
        Element root = null;
        Element estadisticasEquipo = null;
        Element estadisticasJugador = null;
        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012
            idEquipo = Integer.parseInt(request.getParameter("idEquipo"));
            EstEquipo estEquipo = (EstEquipo)em.find(EstEquipo.class, idEquipo);
            if (estEquipo != null) {
                // Estadísticas del equipo
                root = new Element("estadisticas");
                estadisticasEquipo = new Element("equipo");

                estadisticasEquipo.setAttribute("partidos",Integer.toString(estEquipo.getPartidos()));
                estadisticasEquipo.setAttribute("gan"     ,Integer.toString(estEquipo.getGanados()));
                estadisticasEquipo.setAttribute("per"     ,Integer.toString(estEquipo.getPerdidos()));
                estadisticasEquipo.setAttribute("aba"     ,Integer.toString(estEquipo.getAbandonos()));
                estadisticasEquipo.setAttribute("minutos" ,Float.toString  (estEquipo.getMinutos()));
                estadisticasEquipo.setAttribute("puntos"  ,Integer.toString(estEquipo.getPuntos()));
                estadisticasEquipo.setAttribute("t1"      ,Integer.toString(estEquipo.getTiro1()));
                estadisticasEquipo.setAttribute("p1"      ,Integer.toString(estEquipo.getPto1()));
                estadisticasEquipo.setAttribute("por1"    ,Float.toString  ((float)(estEquipo.getPorc1()) ));
                estadisticasEquipo.setAttribute("t2"      ,Integer.toString(estEquipo.getTiro2()));
                estadisticasEquipo.setAttribute("p2"      ,Integer.toString(estEquipo.getPto2()));
                estadisticasEquipo.setAttribute("por2"    ,Float.toString  ((float)(estEquipo.getPorc2()) ));
                estadisticasEquipo.setAttribute("t3"      ,Integer.toString(estEquipo.getTiro3()));
                estadisticasEquipo.setAttribute("p3"      ,Integer.toString(estEquipo.getPto3()));
                estadisticasEquipo.setAttribute("por3"    ,Float.toString  ((float)(estEquipo.getPorc3()) ));

                estadisticasEquipo.setAttribute("rd",Integer.toString(estEquipo.getRebotesDefensa()));
                estadisticasEquipo.setAttribute("ro",Integer.toString(estEquipo.getRebotesAtaque()));
                estadisticasEquipo.setAttribute("as",Integer.toString(estEquipo.getAsistencias()));
                estadisticasEquipo.setAttribute("br",Integer.toString(estEquipo.getRobos()));
                estadisticasEquipo.setAttribute("bp",Integer.toString(estEquipo.getPerdidas()));
                estadisticasEquipo.setAttribute("tf",Integer.toString(estEquipo.getTapones()));
                estadisticasEquipo.setAttribute("tc",Integer.toString(estEquipo.getTaponesContra()));
                estadisticasEquipo.setAttribute("fc",Integer.toString(estEquipo.getFaltas()));
                estadisticasEquipo.setAttribute("fr",Integer.toString(estEquipo.getFaltasContra()));
                estadisticasEquipo.setAttribute("vt",Integer.toString(estEquipo.getValoracion()));
                estadisticasEquipo.setAttribute("vm",Float.toString(estEquipo.getValMedia()));

                root.addContent(estadisticasEquipo);

                Element jugadores = new Element("jugadores");

                // Plantilla
                Query q = em.createNamedQuery("Plantilla.findByEquipoId");
                q.setParameter("equipoId", idEquipo);
                List<Plantilla> lp = (List<Plantilla>)q.getResultList();

                for(Plantilla p : lp)
                {
                    EstJugador estJugador = (EstJugador)em.find(EstJugador.class, p.getPlantillaPK().getJugadorId());
                    if (estJugador != null) {

                        estadisticasJugador = new Element("jugador");

                        estadisticasJugador.setAttribute("id", Integer.toString(estJugador.getJugadorId()));

                        estadisticasJugador.setAttribute("partidos" ,Integer.toString(estJugador.getPartidos()));
                        estadisticasJugador.setAttribute("minutos"  ,Float.toString  (estJugador.getMinutos()));
                        estadisticasJugador.setAttribute("puntos"   ,Integer.toString(estJugador.getPuntos()));
                        estadisticasJugador.setAttribute("t1"       ,Integer.toString(estJugador.getTiro1()));
                        estadisticasJugador.setAttribute("p1"       ,Integer.toString(estJugador.getPto1()));
                        estadisticasJugador.setAttribute("por1"     ,Float.toString  (estJugador.getPorc1()));
                        estadisticasJugador.setAttribute("t2"       ,Integer.toString(estJugador.getTiro2()));
                        estadisticasJugador.setAttribute("p2"       ,Integer.toString(estJugador.getPto2()));
                        estadisticasJugador.setAttribute("por2"     ,Float.toString((estJugador.getPorc2())));
                        estadisticasJugador.setAttribute("t3"       ,Integer.toString(estJugador.getTiro3()));
                        estadisticasJugador.setAttribute("p3"       ,Integer.toString(estJugador.getPto3()));
                        estadisticasJugador.setAttribute("por3"     ,Float.toString((estJugador.getPorc3())));

                        estadisticasJugador.setAttribute("rd"   ,Integer.toString   (estJugador.getRebotesDefensa()));
                        estadisticasJugador.setAttribute("ro"   ,Integer.toString   (estJugador.getRebotesAtaque()));
                        estadisticasJugador.setAttribute("as"   ,Integer.toString   (estJugador.getAsistencias()));
                        estadisticasJugador.setAttribute("br"   ,Integer.toString   (estJugador.getRobos()));
                        estadisticasJugador.setAttribute("bp"   ,Integer.toString   (estJugador.getPerdidas()));
                        estadisticasJugador.setAttribute("tf"   ,Integer.toString   (estJugador.getTapones()));
                        estadisticasJugador.setAttribute("tc"   ,Integer.toString   (estJugador.getTaponesContra()));
                        estadisticasJugador.setAttribute("fc"   ,Integer.toString   (estJugador.getFaltas()));
                        estadisticasJugador.setAttribute("fr"   ,Integer.toString   (estJugador.getFaltasContra()));
                        estadisticasJugador.setAttribute("vt"   ,Integer.toString   (estJugador.getValoracion()));
                        estadisticasJugador.setAttribute("vm"   ,Float.toString     (estJugador.getValMedia()));
                        jugadores.addContent(estadisticasJugador);

                     }
                }

                root.addContent(jugadores);

                doc = new Document(root);
                xmlOut = new XMLOutputter();
                output = xmlOut.outputString(doc);
            }
        } catch (Exception e) {
            log.error("wsEstadisticas", e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
            try {
                PrintWriter out = response.getWriter();
                out.print(output);
            } catch (Exception e) {
            }
        }
    }
/*
    public List<Equipo> dameListaEquipos(int idUsuario) {

        List<Equipo> l = null;
        EntityManager em = null;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            Query q = em.createNamedQuery("Equipo.findByIdUsuario");
            q.setParameter("idUsuario", idUsuario);


            l = (List<Equipo>)q.getResultList();
        } catch (Exception e) {
            log.error("[ERROR][bajaServicio]: ", e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return l;
    }
*/
    public int wsComprobarSesion(String idSesion) {
        EntityManager em        = null;
        int           retorno   = -1;

        if ( idSesion.length() < 10 ) {
            return retorno;
        }
        try {
            em = emfBasket.createEntityManager(); // check 08.08.2012
            retorno = comprobarSesion(idSesion, em);
        } catch (Exception e) {
            log.error("[ERROR][bajaServicio]: ", e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return retorno;
    }

    public int comprobarSesion(String idSesion, EntityManager em) {

        long tiempoI = new GregorianCalendar().getTimeInMillis();
        int retorno = -1;

        log.info("Buscando sesion: " + idSesion);
        if ( idSesion.length() < 10 ) {
            return retorno;
        }
        
        try {
            Query q = em.createNamedQuery("Sesion.findByIdSesion");
            q.setParameter("idSesion", idSesion);
            Sesion s = null;
            s = (Sesion)q.getSingleResult();

            if (s!=null) {
                retorno = s.getIdUsuario();
            }            
        } catch (NoResultException e) {
            retorno = -1;
            log.error("[ERROR][Sesion no existe]: " + idSesion);
        } catch (Exception e) {
            log.error("[ERROR][comprobarSesion]: " , e);
            retorno = -2;
        }

        return retorno;

    }
/*
    private int comprobarSesion(String idSesion) {

        EntityManager em = null;
        int retorno = -1;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            retorno = comprobarSesion(idSesion, em);
        } catch (Exception e) {
            log.error("[ERROR][comprobarSesion]: " , e);
            retorno = -2;
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        log.info("Devolviendo en idUsuario: " + retorno);

        return retorno;
    }
*/

    /* Mismo cometido que ComprobarSesion
     * devuelve 0 si el equipo es del usuario propietario de la sesión
     * -1 si la sesión no existe
     * -2 error indeterminado
     * -5 si no existe el equipo
     * -6 si el equipo no es del usuario
     *
     */
 /*
    private int comprobarSesionEquipo(String p_sesion, int p_equipo) {

        EntityManager em = null;
        int retorno = -1;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            retorno = comprobarSesionEquipo(p_sesion, p_equipo, em);

        } catch (Exception e) {
            log.error("[ERROR][comprobarSesion]: " , e);
            retorno = -2;
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return retorno;
    }
*/

    public int comprobarSesionEquipo(String p_sesion, int p_equipo, EntityManager em) {

        int usuario_id;
        int retorno=-5;
        if ( p_sesion.length() < 10 ) {
            return retorno;
        }

        try {
            usuario_id = comprobarSesion(p_sesion, em);
            if ( usuario_id <0 ) {
                retorno= usuario_id;
            }  else {
                Query q = em.createNamedQuery("Equipo.findById");
                q.setParameter("idEquipo", p_equipo);
                Equipo e = null;
                e = (Equipo)q.getSingleResult();
                if (e==null) {
                    log.debug("[ERROR][Sesion Equipo no existe]: " + p_equipo);
                    retorno= -5;
                } else {
                    if ( e.getUsuario().getId() == usuario_id) {
                        retorno=usuario_id;
                    } else {
                        log.debug("[ERROR][Sesion Equipo de otro usuario]: " + p_equipo+ " "+ usuario_id);
                        retorno=-6;
                    }
                }
            }
        } catch (NoResultException e) {
            retorno = -5;
            log.debug("[ERROR][Equipo no existe]: " + p_equipo);
        } catch (Exception e) {
            log.error("[ERROR][comprobarSesion]: " , e);
            retorno = -2;
        }

        return retorno;
    }

/*
    public int grabaSesion(int idUsuario, String idSesion) {
        int retorno = 1;

        EntityManager em = null;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012
            log.debug("*** debug login" + idUsuario );

            em.getTransaction().begin();
            Query q = em.createNamedQuery("Sesion.removeByIdUsuario");
            q.setParameter("idUsuario", idUsuario);
            q.setParameter("idSesion", idSesion);

//            q = em.createNamedQuery("Sesion.removeByIdSesion");
            q.executeUpdate();
            log.debug("*" + idSesion);

            Sesion s = new Sesion();
            s.setIdUsuario(idUsuario);
            s.setIdSesion(idSesion);

            em.persist(s);
            em.getTransaction().commit();
        } catch (Exception e) {
            log.error("[ERROR][grabaSesion]: " , e);
            retorno = -2;
            if (em     != null && em.getTransaction().isActive() )
                em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return retorno;
    }
    */
    public int grabaSesion(int idUsuario, String idSesion, EntityManager em) {
        int retorno = 1;

        Query q = em.createNamedQuery("Sesion.removeByIdUsuario");
        q.setParameter("idUsuario", idUsuario);
        q.setParameter("idSesion", idSesion);
        q.executeUpdate();
        log.debug("*" + idSesion);

        Sesion s = new Sesion();
        s.setIdUsuario(idUsuario);
        s.setIdSesion(idSesion);

        em.persist(s);

        return retorno;
    }

/* 
 * 10/05/2013
 * VERSION PREPARADA EN PREVISION A LOS BLOQUEOS DE LA TABLA DE SESIONES
    
    public int grabaSesion(int idUsuario, String idSesion) {
        int retorno = 1;

        EntityManager em = null;
        
        try {
            em = emfBasket.createEntityManager();
            em.getTransaction().begin();
            
            Query q = em.createNamedQuery("Sesion.removeByIdUsuario");
            q.setParameter("idUsuario", idUsuario);
            q.setParameter("idSesion", idSesion);
            q.executeUpdate();

            Sesion s = new Sesion();
            s.setIdUsuario(idUsuario);
            s.setIdSesion(idSesion);

            em.persist(s);
            em.getTransaction().commit();
            
        } catch (Exception e) {
            log.error("[ERROR][grabaSesion]: " , e);
            retorno = -2;
            if (em     != null && em.getTransaction().isActive() )
                em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { }
        }
        
        return retorno;
    }
 * 
 */    
       
    
    public Equipo BuscarEquipo ( EntityManager em,  int id_buscar)
    {
            Query q = em.createNamedQuery("Equipo.findById");
            q.setParameter("idEquipo", id_buscar);

            List<Equipo> lista = q.getResultList();

            if (lista.isEmpty()) {
                return null;
            }
            return lista.get(0);
    }

    private String dameNombreURL(String nombre, String nick) {
        String retorno = null;

        retorno = nombre.toLowerCase() + "-" + nick.toLowerCase();
        retorno = retorno.replace(" ", "-");

        return retorno;
    }

    /* Apunta la fecha en que el usuario aceptó el EULA */
    public String wsAceptarEula (HttpServletRequest request, HttpServletResponse response) {
        String          output  = "error=-5;";
        EntityManager   em      = null;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            HttpSession     sesion = request.getSession();
            int             idUsuario = comprobarSesion(sesion.getId(),em);
            
            // Iniciamos la transacción
            em.getTransaction().begin();

            if (idUsuario < 0) {
                output="error=-4;";
            } else {
                log.info("EULA Buscando usuario: " + idUsuario);
                Query q = em.createNamedQuery("Usuario.findById");

                q.setParameter("id", idUsuario);
                Usuario u = (Usuario)q.getSingleResult();
                u.setfEula( new Date() );

    log.info( "EULA: guardando: " + idUsuario+ " fecha" + u.getfEula());

                em.persist(u);

                output="error=0;";
                em.getTransaction().commit();
            }
        } catch (Exception e) {
            log.error("[ERROR][AceptarEula]: " , e);
            output="error=-6;";
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { }; // revisado 09/08/2012
        }


        return output;
    }
/* Banea a un usuario su cuenta durante un tiempo especificado */
/* Parametros: usuario_id - usuario a banear
 *             tiempo     >0 y <500 (banea el número de horas)
 *                        >500 ( baneo definitivo )
 */
    public String wsBanearUsuario (HttpServletRequest request, HttpServletResponse response) {
        String          output  = "error=-5;";
        EntityManager   em      = null;
        int             par_usuario_id;
        long            par_tiempo;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            // Iniciamos la transacción
            em.getTransaction().begin();

            par_usuario_id  = Integer.parseInt(request.getParameter("usuario_id"));
            par_tiempo      = Integer.parseInt(request.getParameter("tiempo"));

            if (par_usuario_id <= 0) {
                output="error=-2;";
            } else {
log.info("Banear Buscando usuario: " + par_usuario_id);
                Query q = em.createNamedQuery("Usuario.findById");

                q.setParameter("id", par_usuario_id);
                Usuario u = (Usuario)q.getSingleResult();

                if ( par_tiempo > 0) {

                    long tiempo = new Date().getTime();
                    tiempo = tiempo + (par_tiempo*60*60*1000);

                    u.setfAdmision ( new Date(tiempo) );
log.info("Baneo temporal: " + par_tiempo );
                }
                if ( par_tiempo > 500 ) {

                    u.setStatus(6);
log.info("Baneo definitivo: " + par_tiempo );
                }

                em.persist(u);

                output="error=0;";
                em.getTransaction().commit();
            }
        } catch (Exception e) {
            log.error("[ERROR][Banear]: " , e);
            output="error=-3;";
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { }; // revisado 09/08/2012
        }


        return output;
    }

    public String wsDesbanearUsuario (HttpServletRequest request, HttpServletResponse response) {
        String          output  = "error=-5;";
        EntityManager   em      = null;
        String          par_nick;

        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            // Iniciamos la transacción
            em.getTransaction().begin();

            par_nick    = request.getParameter("nick");

            if (par_nick == null || par_nick.length()== 0) {
                output="error=-2;";
            } else {
log.info("Desbanear Buscando usuario: " + par_nick);
                Query q = em.createNamedQuery("Usuario.findByNick");

                q.setParameter("nick", par_nick.toLowerCase().trim());
                Usuario u = (Usuario)q.getSingleResult();

                u.setfAdmision ( new Date() );

                if ( u.getStatus() == 6)
                    u.setStatus(1);

                em.persist(u);

                output="error=0;";
                em.getTransaction().commit();
            }
        } catch (Exception e) {
            log.error("[ERROR][DesBanear]: " , e);
            output="error=-3;";
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { }; // revisado 09/08/2012
        }
        return output;
    }

    //  version 2.6  Obsoleta
    public String wsCheckSessionPrivate2_6 ( HttpServletRequest request, HttpServletResponse response ) {

        long        ini         = new GregorianCalendar().getTimeInMillis();
        int         idUsuario   = -1;
        Equipo      equipo      = null;
        Usuario     usuario     = null;
        HttpSession miSesion    = null;
        Boolean     activo      = false;
        Boolean     existe      = true;
        EntityManager em        = null;
        String      retorno     = "";

        try {
            miSesion = request.getSession(); // Por el parametro jsessionid

            if ( miSesion == null || miSesion.getId().length()<10) {
                existe = false;
            }

            // Comprobar si es una sesion activa mirando el atributo "activo" de la sesion
            if (miSesion.getAttribute("activo")!=null) {
                activo = (Boolean)miSesion.getAttribute("activo");
            }

            if ( activo && existe ) { // Si no está activa, no se hace más
                String idSesion   = miSesion.getId();
                int    idEquipo   = Integer.parseInt(request.getParameter("equipoId"));
                String servicio   = null;
                if ( request.getParameter("servicio") != null)
                    servicio = request.getParameter("servicio");

                if (idSesion != null) {
                    em = emfBasket.createEntityManager(); // check 07.08.2012

                    Rank rank = new Rank();
                    LoginAction loginAction = new LoginAction();
                    idUsuario = loginAction.comprobarSesion(idSesion, em);

                    if (idUsuario > 0) {
                        usuario = loginAction.dameUsuario(idUsuario,em);
                        equipo = loginAction.dameEquipo(idEquipo,em);
                        if (equipo.getUsuario().getId()==idUsuario) {

                            retorno += "0|"+idUsuario+"|"+equipo.getUsuario().getNickMostrar()+"|"+
                                        equipo.getNombre()+" "+equipo.getNick()+"|"+usuario.getAdmin()+"|";

                            if ( servicio != null && servicio.compareTo("lobby")==0 ){
                                // Formato LOBBY:
                                // Error | usuario_id | usuario.nick | equipo.nombre | equipo.nick | usuario.admin | usuario.reputacion |
                                // semanal.id | semanal.division | equipo.ranking

                                retorno += equipo.getUsuario().getReputacion() + "|";

                                DatosEquipo datos_equipo = new DatosEquipo();
                                Semanal semanal = datos_equipo.buscarSemanal( loginAction.getEntityManager().createEntityManager(), idEquipo);
                                if (semanal != null) {
                                    retorno += semanal.getTorneoId()+"|"+semanal.getDivision()+"|";
                                } else {
                                    retorno +="0|0|";
                                }
                                retorno += rank.getRankingEquipo( idEquipo, em )+"|";
                            }
                        } else {
                            retorno +="-4|"+idUsuario+"|";
                        }
                    } else {
                        retorno +="-1|"+idUsuario+"|";
                    }
                }
            } else {
                if ( !activo ) {
                    retorno +="-3|"+idUsuario+"|";
                } else {
                    retorno +="-8|0|";
                }
            }
        } catch (Exception e) {
            retorno +="-2|"+e+"|";
            log.error("[ERROR][wsCheckSession]: " , e);
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { }; // revisado 09/08/2012
        }

        long fin = new GregorianCalendar().getTimeInMillis();
        retorno +="|"+(fin-ini)+"|";
        
        return retorno;
    }

    public String wsCheckSessionPrivate ( HttpServletRequest request, HttpServletResponse response ) {

        long        ini         = new GregorianCalendar().getTimeInMillis();
        int         idUsuario   = -1;
        Equipo      equipo      = null;
        Usuario     usuario     = null;
        HttpSession miSesion    = null;
        Boolean     activo      = false;
        Boolean     existe      = true;
        EntityManager em        = null;
        String      retorno     = "";

        try {
            miSesion = request.getSession(); // Por el parametro jsessionid

            if ( miSesion == null || miSesion.getId().length()<10) {
                existe = false;
            }

            // Comprobar si es una sesion activa mirando el atributo "activo" de la sesion
            if (miSesion.getAttribute("activo")!=null) {
                activo = (Boolean)miSesion.getAttribute("activo");
            }

            if ( activo && existe ) { // Si no está activa, no se hace más
                String idSesion   = miSesion.getId();
                int    idEquipo   = Integer.parseInt(request.getParameter("equipoId"));
                String servicio   = null;
                if ( request.getParameter("servicio") != null)
                    servicio = request.getParameter("servicio");

                if (idSesion != null) {
                    em = emfBasket.createEntityManager(); // check 07.08.2012

                    Rank rank = new Rank();
                    LoginAction loginAction = new LoginAction();
                    idUsuario = loginAction.comprobarSesion(idSesion, em);

                    if (idUsuario > 0) {
                        usuario = loginAction.dameUsuario(idUsuario,em);
                        equipo = loginAction.dameEquipo(idEquipo,em);
                        if (equipo != null && equipo.getUsuario().getId()==idUsuario) {

                            retorno += "0|"+idUsuario+"|"+equipo.getUsuario().getNickMostrar()+"|"+
                                        equipo.getNombre()+" "+equipo.getNick()+"|"+usuario.getAdmin()+"|";

                            if ( servicio != null && servicio.compareTo("lobby")==0 ){
                                // Formato LOBBY:
                                // Error | usuario_id | usuario.nick | equipo.nombre | equipo.nick | usuario.admin 
                                // | usuario.reputacion | equipo.ranking
                                // | array con 6 ultimos rivales
                                // | flag info extra
                                // Si bit=1 | semanal.id | semanal.division |
                                // Si bit=2 | elo.zona | elo.puntos |
                                // Si bit=4 | elo.division | elo.divisionPuntos

                                retorno += usuario.getReputacion() + "|";
                                retorno += rank.getRankingEquipo( idEquipo, em )+"|";

                                // Calculo de la categoría del equipo
                                retorno += Util.getCategoriaEquipo( equipo ) +"|";

                                // Información Rivales ultimos Partidos
                                UltimosPartidos ultimos=null;
                                try{
                                    Query q = em.createNamedQuery("UltimosPartidos.findByEquipoId");
                                    q.setParameter("equipo_id", equipo.getId());
                                    ultimos = (UltimosPartidos)q.getSingleResult();
                                } catch (NoResultException nre) {
                                }
                                if ( ultimos == null ) {
                                    retorno += "0|0|0|0|0|0";
                                } else {
                                    retorno +=""+ultimos.getEq1()+"|"+ultimos.getEq2()+"|"+ultimos.getEq3()+"|"
                                                 +ultimos.getEq4()+"|"+ultimos.getEq5()+"|"+ultimos.getEq6();
                                }

                                int flag_extra = 0;
                                String retorno_extra="";

                                // Datos Weekly
                                if ( conf.BuscarValorConfiguracionInteger("weekly_ladder") > 0 ) {
                                    DatosEquipo datos_equipo = new DatosEquipo();
                                    Semanal semanal = datos_equipo.buscarSemanal( loginAction.getEntityManager().createEntityManager(), idEquipo);
                                    if (semanal != null) {
log.debug("weekly" + flag_extra);
                                        flag_extra+=1;
log.debug("torneo" + semanal.getTorneoId()+" division"+semanal.getDivision());
                                        retorno_extra += "|"+semanal.getTorneoId()+"|"+semanal.getDivision();
                                    }
                                }
                                // Datos Pool Elo
                                if ( conf.BuscarValorConfiguracionInteger("wbcstar") > 0 ) {
log.debug("config wbcstar" );
                                    if ( equipo.getNivel()>14 ) {

log.debug("equipo > 14" );
                                        Elo elo=null;
                                        try{
                                            Query q = em.createNamedQuery("Elo.findByEquipoId");
                                            q.setParameter("equipo_id", equipo.getId());    
                                            elo = (Elo)q.getSingleResult();
                                        } catch (NoResultException nre) {
                                        }

                                        if ( elo != null) {
log.debug("ELO tiene" );
                                            flag_extra+=2;
                                            retorno_extra += "|" + elo.getZona() +"|"+elo.getElo();

                                            if ( elo.getDivision()>0 ) {
                                                flag_extra+=4;
                                                retorno_extra += "|"+elo.getDivision() +"|"+elo.getDivisionPuntos();
                                                // Si el equipo está encuadrado en una division busco todos los cruces
                                                // para que no sean repetidos
                                                try{
log.debug("ELO tiene division" );
                                                    Query q = em.createNamedQuery("CruceDivision.findByDivisionEquipoId");
                                                    q.setParameter("zona"       , elo.getZona());
                                                    q.setParameter("division"   , elo.getDivision());
                                                    q.setParameter("equipo_id"  , equipo.getId());
                                                    List<CruceDivision> lista_cruce = q.getResultList();
                                                    if ( lista_cruce != null ) {
                                                        retorno_extra += "|" + lista_cruce.size();
                                                        for ( int i=0;i<lista_cruce.size();i++ ) {
log.debug("ELO tiene cruces division" );
                                                            if ( equipo.getId() != lista_cruce.get(i).getId().getEquipoId1() )
                                                                retorno_extra += "|" + lista_cruce.get(i).getId().getEquipoId1();
                                                            else
                                                                retorno_extra += "|" + lista_cruce.get(i).getId().getEquipoId2();
                                                        }
                                                    }
                                                } catch (NoResultException nre) {
                                                    retorno_extra += "|0";
                                                }
                                            }
                                        }
                                    }
                                }
                                retorno += "|"+flag_extra;
                                if ( flag_extra > 0 )
                                    retorno += retorno_extra;

                            }
                        } else {
                            retorno +="-4|"+idUsuario+"|";
                        }
                    } else {
                        retorno +="-1|"+idUsuario+"|";
                    }
                }
            } else {
                if ( !activo ) {
                    retorno +="-3|"+idUsuario+"|";
                } else {
                    retorno +="-8|0|";
                }
            }
        } catch (Exception e) {
            retorno +="-2|"+e+"|";
            log.error("[ERROR][wsCheckSession]: " , e);
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { }; // revisado 09/08/2012
        }

        long fin = new GregorianCalendar().getTimeInMillis();
        retorno +="|"+(fin-ini)+"|";

        return retorno;
    }


    public String wsCheckSessionPublic ( HttpServletRequest request, HttpServletResponse response ) {

        long        ini         = new GregorianCalendar().getTimeInMillis();
        int         idUsuario   = -1;
        Equipo      equipo      = null;
        Usuario     usuario     = null;
        HttpSession miSesion    = null;
        Boolean     activo      = false;
        Boolean     existe      = true;
        EntityManager em        = null;
        String      retorno     = "";

        try {
            miSesion = request.getSession(); // Por el parametro jsessionid

            if ( miSesion == null || miSesion.getId().length()<10 ) {
                existe = false;
            }

            // Comprobar si es una sesion activa mirando el atributo "activo" de la sesion
            if (miSesion.getAttribute("activo")!=null) {
                activo = (Boolean)miSesion.getAttribute("activo");
            }

            if ( activo && existe ) { // Si no está activa, no se hace más
                String idSesion = miSesion.getId();
                int idEquipo = Integer.parseInt(request.getParameter("equipoId"));

                if (idSesion != null) {
                    em = emfBasket.createEntityManager(); // check 08.08.2012

                    LoginAction loginAction = new LoginAction();

                    idUsuario = loginAction.comprobarSesion(idSesion, em);
                    if (idUsuario > 0) {
                        equipo = loginAction.dameEquipo(idEquipo,em);

                        if (equipo.getUsuario().getId()==idUsuario) {
                            retorno +="0|"+idUsuario+"|"+equipo.getUsuario().getNick()+"|"+equipo.getNombre()+" "+equipo.getNick()+"|";
                        } else {
                            retorno +="-4|"+idUsuario+"|";
                        }
                    } else {
                        retorno +="-1|"+idUsuario+"|No hay sesion"+miSesion.getId();
                    }
                }
            } else {
                retorno +="-3|"+idUsuario+"|";
            }
        } catch (Exception e) {
            retorno +="-2|"+e+"|";
            log.error("[ERROR][wsCheckSession]: " , e);
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { }; // revisado 09/08/2012
        }

        long fin = new GregorianCalendar().getTimeInMillis();
        retorno +="|"+(fin-ini)+"|";

        return retorno;
    }



}